package com.gel.codegeneration.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.gel.codegeneration.common.enums.ChatHistoryMessageTypeEnum;
import com.gel.codegeneration.common.enums.ErrorCode;
import com.gel.codegeneration.common.enums.UserRoleEnum;
import com.gel.codegeneration.model.dto.req.chathistory.ChatHistoryQueryRequest;
import com.gel.codegeneration.model.entity.App;
import com.gel.codegeneration.model.entity.User;
import com.gel.codegeneration.service.AppService;
import com.gel.codegeneration.utils.ThrowUtils;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.gel.codegeneration.model.entity.ChatHistory;
import com.gel.codegeneration.mapper.ChatHistoryMapper;
import com.gel.codegeneration.service.ChatHistoryService;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.memory.ChatMemory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 对话历史 服务层实现。
 *
 * @author <a>gel</a>
 */
@Service
@Slf4j
public class ChatHistoryServiceImpl extends ServiceImpl<ChatHistoryMapper, ChatHistory>  implements ChatHistoryService{

    @Resource
    private AppService appService;
    //消息持久化到mysql
    @Override
    public boolean addChatMessage(Long appId, String message, String messageType, Long userId) {
        //参数校验
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        ThrowUtils.throwIf(StrUtil.isBlank(message), ErrorCode.PARAMS_ERROR, "消息内容不能为空");
        ThrowUtils.throwIf(StrUtil.isBlank(messageType), ErrorCode.PARAMS_ERROR, "消息类型不能为空");
        ThrowUtils.throwIf(userId == null || userId <= 0, ErrorCode.PARAMS_ERROR, "用户ID不能为空");
        //验证消息类型的有效性
        ChatHistoryMessageTypeEnum enumByValue = ChatHistoryMessageTypeEnum.getEnumByValue(messageType);
        ThrowUtils.throwIf(enumByValue == null, ErrorCode.PARAMS_ERROR, "不支持的消息类型");
        ChatHistory chatHistory = ChatHistory.builder()
                .appId(appId)
                .message(message)
                .messageType(messageType)
                .userId(userId)
                .build();
        return this.save(chatHistory);


    }
    //关联删除（删除应用时删除会话记忆）
    @Override
    public boolean deleteByAppId(Long appId) {
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        QueryWrapper query = QueryWrapper.create()
                .eq(ChatHistory::getAppId,appId);
        return this.remove(query);
    }

    @Override
    public QueryWrapper getQueryWrapper(ChatHistoryQueryRequest chatHistoryQueryRequest) {
        QueryWrapper queryWrapper = QueryWrapper.create();
        if(chatHistoryQueryRequest == null){
            return queryWrapper;
        }
        queryWrapper
                .eq(ChatHistory::getId, chatHistoryQueryRequest.getId())
                .eq(ChatHistory::getAppId, chatHistoryQueryRequest.getAppId())
                .eq(ChatHistory::getUserId, chatHistoryQueryRequest.getUserId())
                .like(ChatHistory::getMessage, chatHistoryQueryRequest.getMessage());
        //游标查询逻辑
        LocalDateTime lastCreateTime = chatHistoryQueryRequest.getLastCreateTime();
        if(lastCreateTime!=null){
            queryWrapper.lt(ChatHistory::getCreateTime,lastCreateTime);
        }
        //排序
        String sortField = chatHistoryQueryRequest.getSortField();
        String sortOrder = chatHistoryQueryRequest.getSortOrder();
        if(sortField != null){
            queryWrapper.orderBy(sortField, "ascend".equals(sortOrder));
        }else {
            //否则按照创建时间降序
            queryWrapper.orderBy(ChatHistory::getCreateTime,false);
        }
        return queryWrapper;

    }
    @Override
    public int loadChatHistoryToMemory(Long appId, ChatMemory chatMemory, int maxCount) {
        try{
            //构建查询条件，查询最近maxCount条记录，起始点是1，用于排除最新的userMessage
            QueryWrapper queryWrapper = QueryWrapper.create()
                    .eq(ChatHistory::getAppId, appId)
                    .orderBy(ChatHistory::getCreateTime, false)
                    .limit(maxCount);
            List<ChatHistory> historyList = this.list(queryWrapper);
            if (CollUtil.isEmpty(historyList)) {
                return 0;
            }
            //反转数据（因为是按照最近的顺序开始查询的数据）
            List<ChatHistory> chatHistoryList = CollUtil.reverse(historyList);
            //加载之前先清除历史缓存
            chatMemory.clear();
            //按照时间顺序加载到记忆中
            int count = 0;
            for (ChatHistory chatHistory : chatHistoryList) {
                if (chatHistory.getMessageType().equals(ChatHistoryMessageTypeEnum.USER.getValue())) {
                    chatMemory.add(UserMessage.from(chatHistory.getMessage()));
                }
                if (chatHistory.getMessageType().equals(ChatHistoryMessageTypeEnum.AI.getValue())) {
                    chatMemory.add(AiMessage.from(chatHistory.getMessage()));
                }
                count++;
            }
            log.info("成功为appId:{}加载历史对话{}条", appId, count);
            return count;


        }catch (Exception e) {
            log.error("加载历史对话失败,appId:{},error:{}", appId, e);
            return 0;
        }
    }


    @Override
    public Page<ChatHistory> listAppChatHistoryByPage(Long appId, Integer pageSize, LocalDateTime lastUpdateTime, User loginUser) {
        //参数校验
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        ThrowUtils.throwIf(pageSize <= 0 || pageSize > 50, ErrorCode.PARAMS_ERROR, "页面大小必须在1-50之间");
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);
        //权限校验
        App app = appService.getById(appId);
        ThrowUtils.throwIf(app == null, ErrorCode.NOT_FOUND_ERROR, "应用不存在");
        String userRole = loginUser.getUserRole();
        boolean isAdmin= UserRoleEnum.ADMIN.getValue().equals(userRole);
        boolean isCreator= app.getUserId().equals(loginUser.getId());
        ThrowUtils.throwIf(!isAdmin && !isCreator, ErrorCode.NO_AUTH_ERROR, "无权查看该应用的对话历史");
        //构建查询条件
        ChatHistoryQueryRequest queryRequest =new ChatHistoryQueryRequest();
        queryRequest.setAppId(appId);
        queryRequest.setLastCreateTime(lastUpdateTime);
        QueryWrapper queryWrapper = this.getQueryWrapper(queryRequest);
        //查询
        return this.page(Page.of(1,pageSize),queryWrapper);
    }
}
